package cn.wj.school.server.net.handler;

import cn.wj.school.app.dto.LogOutReqMsg;
import cn.wj.school.cloud.dto.SyLoginLogDTO;
import cn.wj.school.common.dto.BaseMsg;

import cn.wj.school.server.cache.NettyChannelMap;
import cn.wj.school.server.net.context.CmdTask;
import cn.wj.school.server.net.context.IoSession;
import cn.wj.school.server.net.utils.ChannelUtils;
import cn.wj.school.server.net.utils.ThreadPoolUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @Author: yueding
 * @Description: 服务端管道处理器
 * @Date: Created in 14:49 2018/12/27
 * @Modified By: yueding Copyright(c) cai-inc.com
 */
@ChannelHandler.Sharable
@Slf4j
public class ServerChannelHandler extends ChannelInboundHandlerAdapter {

    /**
     * channel 激活
     * 
     * @param ctx
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        log.info("====log=客户端已连接:" + ctx.channel().remoteAddress());
        if (!ChannelUtils.addChannelSession(ctx.channel(), new IoSession(ctx.channel()))) {
            ctx.channel().close();
            log.error("Duplicate session,IP=[{}]",ChannelUtils.getIp(ctx.channel()));
        }
    }

    /**
     * channel 失效
     *
     * @param ctx
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // channel失效，从Map中移除
        IoSession session = ChannelUtils.getSessionBy(ctx.channel());
        if (session.getUser() != null) {
            //登出
            CmdTask cmdTask = CmdTask.valueOf(session.getDispatchKey(), session, new LogOutReqMsg());
            ThreadPoolUtils.addTask(cmdTask);
        }
        super.channelInactive(ctx);
    }

    /**
     * @param ctx
     * @param baseMsg
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object baseMsg) throws Exception {
        BaseMsg msg = (BaseMsg)baseMsg;
        log.info("receive pact, content is {}", msg.getClass().getSimpleName());
        final Channel channel = ctx.channel();
        IoSession session = ChannelUtils.getSessionBy(channel);
        // 扔到业务线程池处理
        CmdTask cmdTask = CmdTask.valueOf(session.getDispatchKey(), session, msg);
        ThreadPoolUtils.addTask(cmdTask);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("业务逻辑出错", cause.getMessage());
        Channel channel = ctx.channel();
        if(cause instanceof IOException && channel.isActive()){
            log.error("simpleclient"+channel.remoteAddress()+"异常");
            ctx.close();
        }
    }
}
